package com.relytosoft.mizar.media.analyze.services.controller.structure;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.relytosoft.dubhe.common.core.exception.ServiceException;
import com.relytosoft.dubhe.common.core.object.ResponseResult;
import com.relytosoft.dubhe.common.core.utils.BeanCopyUtils;
import com.relytosoft.dubhe.common.log.annotation.OpLog;
import com.relytosoft.dubhe.common.log.enums.OpTypeEnum;
import com.relytosoft.mizar.media.analyze.api.pojo.dto.StruFeatureExtractionDto;
import com.relytosoft.mizar.media.analyze.api.pojo.query.AyStruDataQuery;
import com.relytosoft.mizar.media.analyze.api.pojo.query.AyStruMotorVehicleSearchQuery;
import com.relytosoft.mizar.media.analyze.api.pojo.query.AyStructurePersonSearchQuery;
import com.relytosoft.mizar.media.analyze.api.pojo.vo.AyFeatureExtractionVo;
import com.relytosoft.mizar.media.analyze.services.service.structure.AyStructureTaskService;
import com.relytosoft.mizar.media.analyze.services.utils.Base64Utils;
import com.relytosoft.mizar.media.common.entity.algo.AYNonVehicle;
import com.relytosoft.mizar.media.common.entity.algo.AYPerson;
import com.relytosoft.mizar.media.common.entity.algo.AYVehicle;
import com.relytosoft.mizar.media.common.entity.algo.AYVideoSlice;
import com.relytosoft.mizar.media.common.entity.pojo.dto.FeatureExtractionReqDto;
import com.relytosoft.mizar.media.common.entity.pojo.request.btdl.common.BtdlDataReq;
import com.relytosoft.mizar.media.common.enums.StructureTypeEnum;
import com.relytosoft.mizar.media.external.api.analyze.service.StructureService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.time.DateUtils;
import org.simpleframework.xml.core.Validate;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * 结构化数据检索
 *
 * @Author SunLi
 * @Date: 2022/6/2 10:19
 * @Version 1.0
 */
@RestController
@RequestMapping("analyze/structure")
@Api(tags = "结构化数据检索")
public class AyStructureSearchController {


    @Resource
    private AyStructureTaskService structureTaskService;
    @Resource
    private StructureService structureService;

    @SaCheckPermission("structure:search:all")
    @OpLog(msg = "结构化综合检索", opType = OpTypeEnum.SELECT)
    @ApiOperation("结构化综合检索")
    @GetMapping("/search/all")
    public ResponseResult<JSONObject> integratedSearch(@Validate AyStruDataQuery basicQuery) {
        validateDate(basicQuery);
        return ResponseResult.ok(structureTaskService.searchAll(basicQuery));
    }

    @SaCheckPermission("structure:search:person")
    @OpLog(msg = "结构化行人结果检索", opType = OpTypeEnum.SELECT)
    @ApiOperation("结构化行人结果检索")
    @GetMapping("/search/person")
    public ResponseResult<JSONObject> personSearch(@Validate AyStruDataQuery basicQuery, AyStructurePersonSearchQuery personQuery) {
        validateDate(basicQuery);
        return ResponseResult.ok(structureTaskService.searchPerson(basicQuery, personQuery));
    }

    @SaCheckPermission("structure:search:motor")
    @OpLog(msg = "结构化机动车结果检索", opType = OpTypeEnum.SELECT)
    @ApiOperation("结构化机动车结果检索")
    @GetMapping("/search/vehicle")
    public ResponseResult<JSONObject> motorVehicleSearch(@Validate AyStruDataQuery basicQuery, AyStruMotorVehicleSearchQuery vehicleQuery) {
        validateDate(basicQuery);
        return ResponseResult.ok(structureTaskService.searchVehicle(basicQuery, vehicleQuery));
    }
    @ApiOperation("结构化图片分析识别")
    @PostMapping("/feature/extraction")
    public ResponseResult featureExtraction(@RequestBody StruFeatureExtractionDto struFeatureExtractionDto){
        String strMsg=validateExtraction(struFeatureExtractionDto);
        if(StrUtil.isNotEmpty(strMsg)){
            return ResponseResult.fail(strMsg);
        }
        Integer targetType=struFeatureExtractionDto.getTargetType();
        FeatureExtractionReqDto reqDto=new FeatureExtractionReqDto();
        reqDto.setTargetType(targetType);
        reqDto.setImageData(Base64Utils.picToBase64(struFeatureExtractionDto.getImageUrl()));
        ResponseResult<BtdlDataReq> res=structureService.featureExtraction(reqDto);
        if(res.getCode()==ResponseResult.SUCCESS){
            BtdlDataReq dataReq= res.getData();
            List<AYVideoSlice> sliceList=dataReq.getVideoSliceListObject().getVideoSlice();
            if(ArrayUtil.isEmpty(sliceList)){
                return ResponseResult.fail("没有识别到数据");
            }
            AYVideoSlice slice=sliceList.get(0);
            if(targetType.equals(StructureTypeEnum.PERSON.getValue())){
                List<AYPerson> personList=slice.getPersonList().getPersonObject();
                return ResponseResult.ok(BeanCopyUtils.copyList(personList,AyFeatureExtractionVo.class));
            }else if(targetType.equals(StructureTypeEnum.VEHICLE.getValue())){
                List<AYVehicle> vehicleList=slice.getMotorVehicleList().getMotorVehicleObject();
                return ResponseResult.ok(BeanCopyUtils.copyList(vehicleList,AyFeatureExtractionVo.class));
            }else {
                List<AYNonVehicle> nonVehicleList=slice.getNonMotorVehicleList().getNonMotorVehicleObject();
                return ResponseResult.ok(BeanCopyUtils.copyList(nonVehicleList,AyFeatureExtractionVo.class));
            }
        }
        return res;
    }


    private void validateDate(AyStruDataQuery basicQuery) {
        if (StrUtil.isEmpty(basicQuery.getStartTime()) || StrUtil.isEmpty(basicQuery.getEndTime())) {
            throw new ServiceException("查询时间不能为空！");
        }
        try {
            Date startTime = DateUtils.parseDate(basicQuery.getStartTime(), new String[]{"yyyy-MM-dd","yyyy-MM-dd HH:mm:ss"});
            Date endTime = DateUtils.parseDate(basicQuery.getEndTime(), new String[]{"yyyy-MM-dd","yyyy-MM-dd HH:mm:ss"});
            if (startTime.after(endTime)) {
                throw new ServiceException("开始时间大于结束时间！");
            }
            basicQuery.setStartTime(DateUtil.formatDateTime(startTime));
            basicQuery.setEndTime(DateUtil.formatDateTime(endTime));
        } catch (Exception ex) {
            throw new ServiceException(ex.getMessage());
        }
    }

    private String validateExtraction(StruFeatureExtractionDto struFeatureExtractionDto){
        if(struFeatureExtractionDto==null){
            return "参数异常";
        }
        Integer targetType=struFeatureExtractionDto.getTargetType();
        if(Objects.isNull(targetType)||targetType==0||targetType> StructureTypeEnum.NON_VEHICLE.getValue()){
            return "targetType参数异常";
        }
        if(StrUtil.isEmpty(struFeatureExtractionDto.getImageUrl())){
            return "imageUrl参数异常";
        }
        return "";
    }
}
